寫到一半,突然意識到有角架、角櫃的存在,所以開始跟三角形搏鬥
希望可以藉由點擊頂點來改變三角形的形狀,但是 ngx-movable 跟我理想的情況有點差距,所以寫了一下 canvas 的作法,用的原理是我唯一會的三角形公式:A平方=B平方+C平方,來計算邊長
做是做出來了,但還要再做拖曳跟轉圈,頓時覺得有點麻煩,還要處理矩形跟圓形,只有30天估計是不夠,除了時間之外還要考慮精神跟心理壓力,卡關卡太久很消耗意志力肌肉,所以又回去找套件
兜兜轉轉最後又回去使用 ngx-moveable,先用裡面的 warpable 將就使用一下,雖然沒有到 canvas一樣那麼直觀,但可以達到一樣效果。
以下提供 ngx-moveable 跟同場加映的 canvas 。
另外也把圖形們做成 ngx-moveable 的元件
詳細程式碼以及如何把圖形拆成元件的請看 Stackblitz 的 Day6,裡面所使用的功能可以到 feature 資料夾看。
import { Component, ElementRef, ViewChild } from '@angular/core';
import { NgxMoveableComponent } from 'ngx-moveable';
@Component({
selector: 'app-triangle',
templateUrl: './triangle.component.html',
styleUrl: './triangle.component.scss',
})
export class TriangleComponent {
@ViewChild('moveableRef') moveableRef!: NgxMoveableComponent;
@ViewChild('triangleRef') triangleRef!: ElementRef<HTMLDivElement>;
draggable: any = true;
throttleDrag: any = 1;
edgeDraggable: any = false;
startDragRotate: any = 0;
throttleDragRotate: any = 0;
warpable: any = true;
rotatable: any = true;
throttleRotate: any = 0;
rotationPosition: any = 'top';
renderDirections: any = ['nw', 'n', 'ne', 'w', 'e', 'sw', 's', 'se'];
onWarp(event: any) {
event.target.style.transform = event.transform;
}
onDrag(e: { target: { style: { transform: any } }; transform: any }) {
e.target.style.transform = e.transform;
}
onRotate(e: {
target: { style: { transform: any } };
drag: { transform: any };
}) {
e.target.style.transform = e.drag.transform;
}
}
<div class="triangle" #triangleRef>安勾</div>
<ngx-moveable
[target]="triangleRef"
[warpable]="warpable"
[renderDirections]="renderDirections"
(warp)="onWarp($event)"
[draggable]="draggable"
[throttleDrag]="throttleDrag"
[edgeDraggable]="edgeDraggable"
[startDragRotate]="startDragRotate"
[throttleDragRotate]="throttleDragRotate"
[rotatable]="rotatable"
[throttleRotate]="throttleRotate"
[rotationPosition]="rotationPosition"
(rotate)="onRotate($event)"
(drag)="onDrag($event)"
></ngx-moveable>
.triangle {
width: 0;
height: 0;
// border-left: 50px solid transparent;
border-right: 100px solid transparent;
border-bottom: 200px solid #007bff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
position: absolute;
color: white;
top: 150px;
left: 200px;
}
<canvas id="myCanvas" width="500" height="500"></canvas>
import { Component } from '@angular/core';
@Component({
selector: 'app-triangle-canvas',
templateUrl: './triangle-canvas.component.html',
styleUrl: './triangle-canvas.component.scss',
})
export class TriangleCanvasComponent {
private canvas: HTMLCanvasElement | undefined;
private context: CanvasRenderingContext2D | undefined;
private points = [
{ x: 50, y: 50 },
{ x: 150, y: 50 },
{ x: 100, y: 150 },
];
private draggingPoint: any = null;
ngAfterViewInit() {
this.canvas = document.getElementById('myCanvas') as HTMLCanvasElement;
this.context = this.canvas.getContext('2d')!;
this.drawTriangle();
this.canvas.addEventListener('mousedown', this.onMouseDown.bind(this));
this.canvas.addEventListener('mousemove', this.onMouseMove.bind(this));
this.canvas.addEventListener('mouseup', this.onMouseUp.bind(this));
}
private drawTriangle() {
if (this.context && this.canvas) {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.context.beginPath();
this.context.moveTo(this.points[0].x, this.points[0].y);
this.context.lineTo(this.points[1].x, this.points[1].y);
this.context.lineTo(this.points[2].x, this.points[2].y);
this.context.closePath();
this.context.strokeStyle = 'black';
this.context.stroke();
this.context.fillStyle = 'rgba(255, 204, 255)';
this.context.fill();
}
}
private onMouseDown(event: MouseEvent) {
if (this.canvas) {
const rect = this.canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
this.points.forEach((point) => {
const distance = Math.sqrt((x - point.x) ** 2 + (y - point.y) ** 2);
if (distance < 10) {
this.draggingPoint = point;
}
});
}
}
private onMouseMove(event: MouseEvent) {
if (this.draggingPoint && this.canvas) {
const rect = this.canvas.getBoundingClientRect();
this.draggingPoint.x = event.clientX - rect.left;
this.draggingPoint.y = event.clientY - rect.top;
this.drawTriangle();
}
}
private onMouseUp() {
this.draggingPoint = null;
}
}